/***************************************************************************\
 * The Mattise Kernel														*
 * Copyright 2007 Matthew Iselin											*
 * Licensed under the GPL													*
 *																			*
 * msr.cc																	*
 *																			*
 * Performs actions on MSRs													*
 *																			*
\***************************************************************************/

#include <system.h>

/// Performs the CPUID instruction
static inline void cpuid( int code, uint_t *a, uint_t *d )
{
	asm volatile( "cpuid" : "=a" (*a), "=d" (*d) : "0" (code) : "ecx", "ebx" );
}

/// CPUID MSR flag
#define CPUID_FLAG_MSR			0x20

/// Detects if the CPU has support for MSRs
bool cpuHasMSR()
{
	// EAX, EDX
	uint_t a,d;
	
	// perform the CPUID
	cpuid( 1, &a, &d );
	
	// return whether we have MSRs or not
	return (d & CPUID_FLAG_MSR);
}

/// Gets a value from an MSR
void cpuGetMSR( uint_t msr, uint_t* lo, uint_t* hi )
{
	asm volatile( "rdmsr" : "=a" (*lo), "=d" (*hi) : "c" (msr) );
}

/// Puts a value into an MSR
void cpuSetMSR( uint_t msr, uint_t lo, uint_t hi )
{
	asm volatile( "wrmsr" : : "a" (lo), "d" (hi), "c" (msr) );
}
